package lotus.blog.lotusblog.socket;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Component
@ServerEndpoint(value = "/game")

public class GameSocket {
    ObjectMapper objectMapper = new ObjectMapper();
    /** 记录当前在线连接数 */
    private static AtomicInteger onlineCount = new AtomicInteger(0);
    private static Map<String, Session> clients = new ConcurrentHashMap<>();
    private static List<Player> playerList = new ArrayList<Player>();
    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) throws IOException {
        onlineCount.incrementAndGet(); // 在线数加1
        clients.put(session.getId(), session);
        Player player = new Player();
        player.setId(session.getId());
        playerList.add(player);
        System.out.println("当前在线人数"+onlineCount.get());

        sendMessage(GameMessage.sendMessage("当前在线人数"+onlineCount.get()),session);
        sendMessage(GameMessage.sendPlayers(playerList),session);
        synchronized(session){
            session.getBasicRemote().sendText(GameMessage.sendPlayer(player));
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) throws JsonProcessingException {
        clients.remove(session.getId());
        playerList.removeIf(x->x.getId()==session.getId());
        onlineCount.decrementAndGet(); // 在线数减1
        sendMessage(GameMessage.sendMessage("当前在线人数"+onlineCount.get()),session);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message
     *            客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) throws JsonProcessingException {
        GameMessage gm = objectMapper.readValue(message,GameMessage.class);
        if (gm.getType().equals("message")){
            this.sendMessage(GameMessage.sendMessage(session.getId()+"：" + gm.getMessage()), session);
        }else if(gm.getType().equals("player")){
            String map= objectMapper.writeValueAsString(gm.getMessage());
            Player player = objectMapper.readValue(map,Player.class);
            changePlayerById(player);
            this.sendMessage(GameMessage.sendPlayers(playerList),session);
        }
    }
    private void changePlayerById(Player player){
        playerList.forEach(x->{
            if(x.getId().equals(player.getId())){
                x.setX(player.getX());
                x.setY(player.getY());
            }
        });
    }

    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    /**
     * 服务端发送消息给客户端
     */
    private void sendMessage(String message, Session fromSession) {
        for (Map.Entry<String, Session> sessionEntry : clients.entrySet()) {
            Session toSession = sessionEntry.getValue();
            synchronized(toSession){
                try{
                    toSession.getBasicRemote().sendText(message);
                }catch (IOException e){
                    e.printStackTrace();
                }

            }

        }
    }

}
